package model.main;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import model.algorithms.Algorithm;
import model.algorithms.BestFit;
import model.algorithms.BruteForceAlgorithm;
import model.algorithms.FirstFit;
import model.config.Config;
import model.framework.Block;
import model.framework.BlockType;
import model.framework.Field;
import model.io.BlockGenerator;

public class Main {
	
	public static void main( String[] args ) {
		
		try {
			List<Algorithm> algos = new ArrayList<Algorithm>();
			algos.add(new FirstFit());
			algos.add(new BestFit());
			//algos.add(new BruteForceAlgorithm());
			
			/* create a list of blocks we can use to test */
			List<BlockType> blockTypes = BlockGenerator.getBlocksTypesFromFile("blockdefinition");
			List<Block> testBlocks = BlockGenerator.getBlocks(blockTypes, 100);
			
			for (Algorithm al : algos) {				
				try {
					long start = System.nanoTime();
					Field field = new Field(10);
					al.run(BlockGenerator.deepcopyBlockList(testBlocks), field);					
					long end = System.nanoTime();
					Config.p(al + " in " + getExecutionTime(start, end),Config.HIGH);
					Config.p("Final height: " + field.getTotalHeight(),Config.HIGH);
					Config.p("Final field: \n" + field,Config.HIGH);
				} catch (Exception e){
					Config.p("Something went wrong in algorithm " + al,Config.HIGH);
					e.printStackTrace();
				}
				
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		
	}
	
	private static String getExecutionTime( long start, long end )	{
		long time = end - start;
		if ( time > 1000000000 )
			return( "executed in: " + ( time / 10000000 ) / 100.0 + " s"  );
		else if ( time > 1000000 )
			return( "executed in: " + ( time / 10000    ) / 100.0 + " ms" );
		else if ( time > 1000 )
			return( "executed in: " + ( time / 10       ) / 100.0 + " us" );
		else
			return( "executed in: " + ( time            )         + " ns" );
	}
}
